package com.ctshk.app.order.train.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.ctshk.common.annotations.Authority;
import com.ctshk.common.constant.RedisConstants;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.RSAUtil;
import com.ctshk.rpc.system.service.ISysPermissionService;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * <p>
 * 权限拦截器适配器
 * </p>
 *
 * @author 李新科
 * @date 2021/5/14 13:43
 */
@Component
public class AuthorityInterceptorAdapter extends HandlerInterceptorAdapter {

    @DubboReference
    ISysPermissionService sysPermissionService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Authority annotation = handlerMethod.getMethod().getAnnotation(Authority.class);
            if(annotation == null) {
                // 方法上取不到则取类上的注解
                annotation = handlerMethod.getMethod().getDeclaringClass().getAnnotation(Authority.class);
            }

            if (annotation == null) {
                return  true;
            } else {
                //权限控制
                Long menuId = null;
                // TODO 管理员账号先直接放行,等前端传入menuId后再删除该逻辑
                TokenUser tokenUser = getCurrentUser(request);
                String userName = tokenUser.getUsername();
                if("admin".equals(userName)) {
                    return true;
                }
                Long currentUserId = tokenUser.getId();
                if (menuId == null || currentUserId == null) {
                    throw new BusinessException(SystemError.USER_1001);
                }
                Result<List<Long>> permission = sysPermissionService.queryPermission(menuId, currentUserId);
                if (!permission.isSuccess()) {
                    throw new BusinessException(SystemError.USER_1001);
                }
                List<Long> userList = permission.getData();
                /*if (CollectionUtils.isEmpty(userList)) {
                    return Result.success();
                    return new AirportExpressOrderCacheDTO(new ArrayList<>(), 0, 1, 10);
                }*/
            }
        }


        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }

    /**
     * 获取当前用户
     * @param request
     * @return
     */
    public TokenUser getCurrentUser(HttpServletRequest request) {
        String token = request.getHeader(RedisConstants.JWT_TOKEN_HEADER);
        if (StringUtils.isBlank(token)) {
            throw new BusinessException(SystemError.USER_1000);
        }
        TokenUser tokenUser = new TokenUser();
        try {
            token = token.replace(RedisConstants.JWT_TOKEN_PREFIX, Strings.EMPTY);
            String tokenDecrypt = RSAUtil.decryptStr(token);
            tokenUser = JSONObject.parseObject(tokenDecrypt, TokenUser.class);
        } catch (Exception e) {
            throw new BusinessException(SystemError.USER_1015);
        }

        return tokenUser;
    }

    /**
     * 获取当前用户
     * @param request
     * @return
     */
    public Long getCurrentUserId(HttpServletRequest request) {
        TokenUser currentUser = getCurrentUser(request);
        return currentUser.getId();
    }


}
